/********************************************************************
* Name: SSAFormFilter.cpp: Impletement class SSAFormFilter.
*
* Description:
*    The main function of this cpp file is to convert vinsts to SSA Form
*
* History:
*     Create: 
*       CrossBit Group, vivy. 2008-3-31 .
*
*     Last Modified: 
*       gxf. 2008-11-15
*
*********************************************************************/

#include "crossbit/VFilter.h"
#include "crossbit/VInst.h"
#include "crossbit/VBlock.h"
#include "crossbit/GLOBAL.h"

using namespace crossbit;

XTUint32 SSAFormFilter::run(VBlock *vb)
{ 
    VBlock::vb_iterator Itr = vb->begin(); 
    VBlock::vb_iterator End = vb->end(); 
    
    //rn_tbl is a rename table 
    XTRegNum rn_tbl[GLOBAL::MAX_VREG] = {0}; 
    XTRegNum n_vreg = 1;    ///< number vregs from 0 to MAX_VREG
    
    // If there is any floating point inst, don't do the optimization 
    // TODO: Floating point optimization is not available now.  
    for(; Itr != End; Itr++) 
    { 
        if(true == IsFloatOp((*Itr) -> getOpcode())){ 
            return (XTUint32)0; 
        } 
    } 

    Itr = vb->begin(); 

    while (Itr != End){ 
        VInst *inst = *Itr; 
        XTInt32 n = inst->getOperandNum();          //Get operand number 
        
        //Handle with all the operand 
        for(XTInt32 i = 1; i <= n; i++){ 
            Operand oprnd = inst->getOperand(i);    //Get the ith operand 
            
//            if (oprnd.reg == 0){                    // skip the special reg
//                continue;
//            }
            if(oprnd.type == Operand::VREG_USE && oprnd.reg > 0){
                oprnd.reg = rn_tbl[oprnd.reg];      //Get it from rename table 
                inst->setOperand(i, oprnd);         //Update the current inst 
            } 
            else if(oprnd.type == Operand::VREG_DEF) 
            { 
                rn_tbl[oprnd.reg] = n_vreg;         //Put it into rename table 
                oprnd.reg = n_vreg; 
                inst->setOperand(i, oprnd);         //Update the current inst

                n_vreg++;
#ifdef DEBUG
                assert(n_vreg <= GLOBAL::MAX_VREG);
#endif
            } 
        } //end of for
        Itr++;
    } //end of while 
    return (XTUint32)1;
}








